package com.customization.commons;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sap.mw.jco.IFunctionTemplate;
import com.sap.mw.jco.JCO;
import com.sap.mw.jco.JCO.FieldIterator;
import com.weaver.integration.datesource.SAPInterationOutUtil;
import com.weaver.integration.log.LogInfo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.collections.MapUtils;
import weaver.angel.action.fna.ActionLogUtil;
import weaver.general.BaseBean;
import weaver.soa.workflow.request.RequestInfo;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class SAPUtil {


    public static String  formatDate(String date) {
        if (!"".equals(date)) {
            date = date.replaceAll("-", "");
        }
        return date;
    }
    public static String  formatDate(String date,String format) {

            if(date.isEmpty()||date.equals("00000000")){
                return  "";
            }
            if(date.contains("-")){
                date=date.replace("-","");
            }
            if(format.contains("-")){
                Date rq = null;
                try {
                    rq = new SimpleDateFormat("yyyyMMdd").parse(date);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                SimpleDateFormat sdf =  new SimpleDateFormat(format);
                date=sdf.format(rq);
            }



        return date;
    }

    /**
     * 传入输入参数，输出输出参数
     * @param functionname
     * @param impParams
     * @param expParams
     * @return
     */
    public static JSONObject  executeRFC4expParams(String functionname,
                                         HashMap<String ,String > impParams,
                                         ArrayList<String> expParams
                                         ) throws Exception {
        return executeRFC(functionname,impParams,new HashMap<String, HashMap<String,String>>(),new HashMap<String, HashMap<String,HashMap<String,String>>>(),expParams,new HashMap<String ,ArrayList<String> >());

    }

    public static JSONObject  executeRFC(String functionname,
                                         HashMap<String ,String > impParams,
                                         HashMap<String, HashMap<String,String>> impStructParams,
                                         HashMap<String, HashMap<String,HashMap<String,String>>> impTableParams,
                                         ArrayList<String> expParams,
                                         HashMap<String ,ArrayList<String> > expTableParams) throws Exception {
        return executeRFC( functionname,
                 impParams,
                impStructParams,
                 impTableParams,
                 expParams,
                 expTableParams, null);
    }
    
    
    /**
     * 传入输入参数map类型
     * @param functionname
     * @param impParams
     * @param impStructParams
     * @param impTableParams
     * @return
     */    
    public static JSONObject  executeRFC(String functionname,
            Map<String ,Object > impParams,
            Map<String, Map<String,Object>> impStructParams,
            Map<String, Map<String,Map<String,Object>>> impTableParams) throws Exception {
		return executeRFC( functionname,
				impParams,
				impStructParams,
				impTableParams,null);
    }

    
    /**
     * 传入输入参数json字符串格式
     * @param functionname
     * @param impParams
     * @param impStructParams
     * @param impTableParams
     * @return
     */       
    public static JSONObject  executeRFC(String functionname,
            String impParams_json,
            String impStructParams_json,
            String impTableParams_json) throws Exception {
    	
    	ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> impParams = mapper.readValue(impParams_json, Map.class);
		Map<String,Map<String,Object>> impStructParams = mapper.readValue(impStructParams_json, Map.class);
    	Map<String, Map<String,Map<String,Object>>> impTableParams = mapper.readValue(impTableParams_json, Map.class);
		
		return executeRFC(functionname,
				impParams,
				impStructParams,
				impTableParams,null);
    }
    
    
    
    
    /**
     *
     * @param functionname RFC函数的名称
     * @param impParams 输入参数
     * @param impStructParams 输入结构
     * @param impTableParams 输入表
     * @param expParams 输出参数
     * @param expTableParams 输出表
     * @return
     */
    public static JSONObject  executeRFC(String functionname,
                                         HashMap<String ,String > impParams,
                                         HashMap<String, HashMap<String,String>> impStructParams,
                                         HashMap<String, HashMap<String,HashMap<String,String>>> impTableParams,
                                         ArrayList<String> expParams,
                                         HashMap<String ,ArrayList<String> > expTableParams, RequestInfo requestInfo) throws Exception {
        String requestid="";
        if(requestInfo!=null) requestid=requestInfo.getRequestid();
        String loginfo="----------"+requestid+"-Start--------------";
        loginfo+= "\n函数名：functionname:"+functionname;
        loginfo+= "\n输入参数：impParams:"+impParams.toString();
        loginfo+= "\n输入结构：impStructParams:"+impStructParams.toString();
        loginfo+= "\n输入表：impTableParams:"+impTableParams.toString();
        loginfo+= "\n输出参数：expParams:"+expParams.toString();
        loginfo+= "\n输出表：expTableParams:"+expTableParams.toString();


        JSONObject reqInfo=new JSONObject();
        reqInfo.put("functionname",functionname);
        reqInfo.put("impParams",impParams);
        reqInfo.put("impStructParams",impStructParams);
        reqInfo.put("impTableParams",impTableParams);

        //===========记录日志 初始化 Start=========
        ActionLogUtil logs=new ActionLogUtil();
        logs.startExec();//标记调用接口开始时间
        logs.setAddr("SAPDEV");//目标地址
        logs.setReqInfo(reqInfo.toString());//请求报文
        logs.setWfId(requestid);//请求ID
        try{
            if(impParams!=null&&impParams.containsKey("OA_REQID")){
                logs.setWfId(impParams.get("OA_REQID").toString());//请求ID
            }
        }catch (Exception e){

        }
        logs.setExeUser(1);//执行人
        logs.setExectype("SAP");
        try{
            if(impParams!=null&&impParams.containsKey("functionname")){
                logs.setExectype(impParams.get("functionname").toString());//函数名称
            }
        }catch (Exception e){

        }
        //===========记录日志 初始化 End=========


        JSONObject result=new JSONObject();
        BaseBean baseBean=new BaseBean();
        String datasourceId = baseBean.getPropValue("angel_fna","SapdatasourceId");//数据源id
        JCO.Function bapi = null;
        //----------------数据配置----------------------------
        SAPInterationOutUtil sapUtil = new SAPInterationOutUtil();
        long startreadSap = System.currentTimeMillis();
        JCO.Client myConnection = (JCO.Client) sapUtil.getConnection(datasourceId, new LogInfo());
        myConnection.connect();
        try {
            JCO.Repository myRepository1 = new JCO.Repository("myRepositroy", myConnection);
            IFunctionTemplate ft1 = myRepository1.getFunctionTemplate(functionname);
            bapi = ft1.getFunction();

            //处理输入--------------------------------------------------
            JCO.ParameterList imList = bapi.getImportParameterList();

            //输入参数
            for (Map.Entry<String, String> entry : impParams.entrySet()) {
                imList.setValue( entry.getValue(), entry.getKey() );//更改为客户对应的数据
            }

            //输入结构
            if(impStructParams.size()>0){
                for (Map.Entry<String, HashMap<String,String>>  entry : impStructParams.entrySet()) {
                    HashMap<String,String> params=entry.getValue();
                    for (Map.Entry<String, String> p : params.entrySet()) {
                        imList.getStructure(entry.getKey()).setValue(p.getValue(), p.getKey());//更改为客户对应的数据
                    }
                }
            }

            //输入表
            if(impTableParams.size()>0){
                for (Map.Entry<String, HashMap<String,HashMap<String,String>>>  entry : impTableParams.entrySet()) {
                    String tableName=entry.getKey();
                    JCO.Table imTable = bapi.getTableParameterList().getTable(tableName);
                    HashMap<String,HashMap<String,String>> params=entry.getValue();
                    for (Map.Entry<String, HashMap<String,String>> row : params.entrySet()) {
                        imTable.appendRow();
                        for (Map.Entry<String, String> cell : row.getValue().entrySet()) {
                            imTable.setValue(cell.getValue(),  cell.getKey());//更改为客户对应的数据
                        }

                    }
                }
            }



            //执行bapi函数
            myConnection.execute(bapi);
            //处理输出--------------------------------------------------
            JCO.ParameterList exList = bapi.getExportParameterList();
            //处理输出参数
            for (int i = 0; i < expParams.size(); i++) {
                result.put(expParams.get(i),exList.getString(expParams.get(i)));
            }


            //处理输出表
            JCO.ParameterList exTable = bapi.getTableParameterList();
            JSONObject table=new JSONObject();
            for (Map.Entry<String, ArrayList<String>> entry : expTableParams.entrySet()) {
                String tableName = entry.getKey();//sap输出表的名称//更改为客户对应的数据
                ArrayList<String>  params=entry.getValue();
                JCO.Table exTab = exTable.getTable(tableName);
                int size = exTab.getNumRows();//获取输出表的行数
                JSONArray rows=new JSONArray();
                for (int i = 0; i < size; i++) {
                    exTab.setRow(i);//获取第i行
                    JSONObject row=new JSONObject();
                    for (int j = 0; j< params.size(); j++) {
                        row.put(params.get(j),exTab.getString(params.get(j)));
                    }
                    rows.add(row);
                }
                table.put(tableName,rows);
            }
            if(expTableParams.size()>0){
                result.put("table",table);
            }
            //处理表结束
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (null != myConnection) {
                JCO.releaseClient(myConnection);//重要！！！！！必须要有
            }
        }

        //===========记录日志 结尾 Start=========
        logs.setRepInfo(result.toString());//响应报文
        String rfcNotSaveLog=baseBean.getPropValue("angel_fna","rfcNotSaveLog");
        if(rfcNotSaveLog.indexOf(functionname)<0) {
            logs.endExec();//执行并保存日志
        }
        //===========记录日志 结尾 END=========
        long jkhs=System.currentTimeMillis() - startreadSap;
        loginfo+="\n执行"+functionname+"耗时"+jkhs+"ms";
        loginfo+="\n返回结果：:"+result.toString();
        loginfo+="\n----------"+requestid+"-END-----------";
        Console.log(loginfo);

        return  result;
    }
    
    /**
    *
    * @param functionname RFC函数的名称
    * @param impParams 输入参数
    * @param impStructParams 输入结构
    * @param impTableParams 输入表
    * @param expParams 输出参数
    * @param expTableParams 输出表
    * @return
    */
   public static JSONObject  executeRFC(String functionname,
                                        Map<String ,Object > impParams,
                                        Map<String, Map<String,Object>> impStructParams,
                                        Map<String, Map<String,Map<String,Object>>> impTableParams, RequestInfo requestInfo) throws Exception {
       String requestid="";if(requestInfo!=null) requestid=requestInfo.getRequestid();
       String loginfo="----------"+requestid+"-Start--------------";
       loginfo+= "\n函数名：functionname:"+functionname;

       JSONObject reqInfo=new JSONObject();
       reqInfo.put("functionname",functionname);
       reqInfo.put("impParams",impParams);
       reqInfo.put("impStructParams",impStructParams);
       reqInfo.put("impTableParams",impTableParams);

       //===========记录日志 初始化 Start=========
       ActionLogUtil logs=new ActionLogUtil();
       logs.startExec();//标记调用接口开始时间
       logs.setAddr("SAPDEV");//目标地址
       logs.setReqInfo(reqInfo.toString());//请求报文
       logs.setWfId(requestid);//请求ID
       try{
           if(impParams!=null&&impParams.containsKey("OA_REQID")){
               logs.setWfId(impParams.get("OA_REQID").toString());//请求ID
           }
       }catch (Exception e){

       }
       logs.setExeUser(1);//执行人
       logs.setExectype("SAP");
       try{
           if(impParams!=null&&impParams.containsKey("functionname")){
               logs.setExectype(impParams.get("functionname").toString());//函数名称
           }
       }catch (Exception e){

       }
       //===========记录日志 初始化 End=========




       JSONObject result=new JSONObject();
       BaseBean baseBean=new BaseBean();
       String datasourceId = baseBean.getPropValue("angel_fna","SapdatasourceId");//数据源id
       JCO.Function bapi = null;
       //----------------数据配置----------------------------
       SAPInterationOutUtil sapUtil = new SAPInterationOutUtil();
       long startreadSap = System.currentTimeMillis();
       JCO.Client myConnection = (JCO.Client) sapUtil.getConnection(datasourceId, new LogInfo());
       myConnection.connect();
       try {
           JCO.Repository myRepository1 = new JCO.Repository("myRepositroy", myConnection);
           IFunctionTemplate ft1 = myRepository1.getFunctionTemplate(functionname);
           bapi = ft1.getFunction();

           //处理输入--------------------------------------------------
           JCO.ParameterList imList = bapi.getImportParameterList();

           if(MapUtils.isNotEmpty(impParams)){
	           loginfo+= "\n输入参数：impParams:"+impParams.toString();
	           //输入参数
	           for (Map.Entry<String, Object> entry : impParams.entrySet()) {
	               imList.setValue( entry.getValue(), entry.getKey() );//更改为客户对应的数据
	           }
           }


           //输入结构
           if(MapUtils.isNotEmpty(impStructParams)){
               loginfo+= "\n输入结构：impTableParams:"+impStructParams.toString();
               for (Map.Entry<String, Map<String,Object>>  entry : impStructParams.entrySet()) {
                   Map<String,Object> params=entry.getValue();
                   for (Map.Entry<String, Object> p : params.entrySet()) {
                       imList.getStructure(entry.getKey()).setValue(p.getValue(), p.getKey());//更改为客户对应的数据
                   }
               }
           }

           //输入表
           if(MapUtils.isNotEmpty(impTableParams)){
               loginfo+= "\n输入表：impTableParams:"+impTableParams.toString();
               for (Map.Entry<String, Map<String,Map<String,Object>>>  entry : impTableParams.entrySet()) {
                   String tableName=entry.getKey();
                   JCO.Table imTable = bapi.getTableParameterList().getTable(tableName);
                   Map<String,Map<String,Object>> params=entry.getValue();
                   for (Map.Entry<String, Map<String,Object>> row : params.entrySet()) {
                       imTable.appendRow();
                       for (Map.Entry<String, Object> cell : row.getValue().entrySet()) {
                           imTable.setValue(cell.getValue(),  cell.getKey());//更改为客户对应的数据
                       }

                   }
               }
           }

           //执行bapi函数
           myConnection.execute(bapi);
           //处理输出--------------------------------------------------
           JCO.ParameterList exList = bapi.getExportParameterList();
           if(exList!=null){

               FieldIterator fileds = exList.fields();
    		   new BaseBean().writeLog(">>>sapUtils:function:"+functionname);
//    		   JSONObject output_fileds = new JSONObject();
    			for (; fileds.hasMoreElements();) {
    				JCO.Field tabField = fileds.nextField();
    				new BaseBean().writeLog(">>>sapUtils:filed:"+tabField.getName());
    				new BaseBean().writeLog(">>>sapUtils:filedvalue:"+tabField.getString());
    				result.put(tabField.getName(), tabField.getString());
    			}
//                result.put("ouFileds", output_fileds);
           }


            //处理输出表
            JCO.ParameterList exTable = bapi.getTableParameterList();
            JSONObject output_tables = new JSONObject();
            if(exTable!=null){
            	   FieldIterator tables = exTable.fields();
                   for(;tables.hasMoreElements();){
                	   JCO.Field table = tables.nextField();
       					//new BaseBean().writeLog(">>>>>>>>>sapUtils:table:"+table.getName());
                       JCO.Table exTab = exTable.getTable(table.getName());
                       //new BaseBean().writeLog(">>>>>>>>>sapUtils:table.getNumRows:"+exTab.getNumRows());
                       JSONObject rows = new JSONObject();
                       //new BaseBean().writeLog(">>>>>>>>>sapUtils:exTab.getRow():"+exTab.getRow());

                       for(;exTab.getNumRows()>0 ;){
                    	   int row = exTab.getRow();
                    	   //new BaseBean().writeLog(">>>>>>>>>row:"+row);
                           FieldIterator tab_fileds = exTab.fields();
                           JSONObject output_table_files = new JSONObject();
                           for(;tab_fileds.hasMoreElements();){
    	                       	JCO.Field tab_filed = tab_fileds.nextField();
    	           				output_table_files.put(tab_filed.getName(), tab_filed.getString());
                           }
                    	   rows.put(row, output_table_files);
                    	   if(!exTab.nextRow()){
                    		   break;
                    	   }
                       }

                   	output_tables.put(table.getName(), rows);
                   }
            }


            result.put("table", output_tables);

           //处理表结束
       } catch (Exception e) {
           Console.log(loginfo);
           loginfo+="\n----------报错 "+requestid+"-END-----------";
           Console.log(e.toString());
           e.printStackTrace();
           throw e;
       } finally {
           if (null != myConnection) {
               JCO.releaseClient(myConnection);//重要！！！！！必须要有
           }
       }

       //===========记录日志 结尾 Start=========
       logs.setRepInfo(result.toString());//响应报文
       String rfcNotSaveLog=baseBean.getPropValue("angel_fna","rfcNotSaveLog");
       if(rfcNotSaveLog.indexOf(functionname)<0) {
           logs.endExec();//执行并保存日志
       }
       //===========记录日志 结尾 END=========


       long jkhs=System.currentTimeMillis() - startreadSap;
       loginfo+="\n执行"+functionname+"耗时"+jkhs+"ms";
       loginfo+="\n返回结果：:"+result.toString();
       loginfo+="\n----------"+requestid+"-END-----------";
       Console.log(loginfo);

       return  result;
   }
       
    
}
